#ifndef SCRIPT_EXECUTOR_H
#define SCRIPT_EXECUTOR_H
#include <functional>
#include <qstringlist.h>
#include "Def.h"

class SDK_EXPORT_API ScriptCommandUnit
{
public:
	QString help;
	QString package;
	QString module;
	QString function;
	QString example;
	QString description;
	std::function<bool(const QStringList&,QString*)> call;

	template<class A>
	QString buildArgument(const A& a)
	{
		return QString("%1").arg(a);
	}

	template<class A,class B>
	QString buildArgument(const A& a,const B& b)
	{
		return QString("%1;%2").arg(a).arg(b);
	}

	template<class A,class B,class C>
	QString buildArgument(const A& a,const B& b,const C& c)
	{
		return QString("%1;%2;%3").arg(a).arg(b).arg(c);
	}

	template<class A,class B,class C,class D>
	QString buildArgument(const A& a,const B& b,const C& c,const D& d)
	{
		return QString("%1;%2;%3;%4").arg(a).arg(b).arg(c).arg(d);
	}

	QString buildExample(const QString& argument)
	{
		return QString("(%1)(%2)(%3)(%4)").arg(package).arg(module).arg(function).arg(argument);
	}

	bool execute(const QStringList& argument,QString* error = nullptr);
};

class AsyncScriptExecutorPrivate;
class AsyncScriptExecutor : public PrivateClassHolder<AsyncScriptExecutorPrivate>
{
public:
	virtual void setFinishedCallback(const std::function<void()>& cb) = 0;
	virtual void execute(const QString& script) = 0;
	virtual void stop() = 0;
	virtual bool running()const = 0;
};

class ScriptExecutor
{
public:
	virtual QList<ScriptCommandUnit> getScriptCommandUnitList()const = 0;
	virtual void registerCommand(const ScriptCommandUnit& command) = 0;
	virtual bool execute(const QString& package,const QString& module,const QString& function,const QStringList& argument,QString* error = nullptr) = 0;
	virtual bool execute(const QString& line,QString* error = nullptr) = 0;
	virtual bool executeScript(const QString& script,QString* error = nullptr) = 0;

	virtual AsyncScriptExecutor* getAsyncScriptExecutor()const = 0;
};

#endif